#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
改进的CodeBuddy登录脚本
尝试多种登录入口点和方法
"""

import requests
from urllib.parse import unquote, parse_qs, urlparse
import re
from bs4 import BeautifulSoup
import json

class ImprovedCodeBuddyLogin:
    def __init__(self):
        self.session = requests.Session()
        self.setup_headers()
        
    def setup_headers(self):
        """设置浏览器请求头"""
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
            "Accept-Encoding": "gzip, deflate, br",
            "DNT": "1",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1"
        })
    
    def test_multiple_entry_points(self):
        """测试多个可能的登录入口点"""
        print("🔍 测试多个登录入口点...")
        
        entry_points = [
            "https://www.codebuddy.ai",
            "https://www.codebuddy.ai/login",
            "https://www.codebuddy.ai/auth",
            "https://www.codebuddy.ai/console",
            "https://www.codebuddy.ai/auth/realms/copilot",
            "https://www.codebuddy.ai/auth/realms/copilot/protocol/openid-connect/auth?client_id=console&redirect_uri=https%3A%2F%2Fwww.codebuddy.ai%2Fconsole&response_type=code"
        ]
        
        working_urls = []
        
        for url in entry_points:
            try:
                print(f"\n📡 测试: {url}")
                response = self.session.get(url, allow_redirects=True, timeout=10)
                
                print(f"  状态码: {response.status_code}")
                print(f"  最终URL: {response.url}")
                
                if response.status_code == 200:
                    working_urls.append((url, response))
                    print(f"  ✅ 可访问")
                    
                    # 检查是否包含登录表单
                    if "login" in response.text.lower() or "username" in response.text.lower():
                        print(f"  🔐 包含登录表单")
                        
                        # 尝试解析登录表单
                        login_form = self.parse_login_form(response)
                        if login_form:
                            print(f"  📝 找到登录表单: {login_form['action']}")
                            return login_form, response
                else:
                    print(f"  ❌ 不可访问 ({response.status_code})")
                    
            except Exception as e:
                print(f"  ❌ 请求失败: {e}")
        
        return None, None
    
    def parse_login_form(self, response):
        """解析登录表单"""
        try:
            soup = BeautifulSoup(response.text, 'html.parser')
            
            # 查找登录表单
            forms = soup.find_all('form')
            
            for form in forms:
                # 检查表单是否包含用户名和密码字段
                username_field = form.find('input', {'name': re.compile(r'username|email|user')})
                password_field = form.find('input', {'type': 'password'})
                
                if username_field and password_field:
                    action = form.get('action', '')
                    method = form.get('method', 'POST').upper()
                    
                    # 处理相对URL
                    if action.startswith('/'):
                        base_url = f"{urlparse(response.url).scheme}://{urlparse(response.url).netloc}"
                        action = base_url + action
                    elif not action.startswith('http'):
                        action = response.url
                    
                    # 获取所有隐藏字段
                    hidden_fields = {}
                    for hidden in form.find_all('input', {'type': 'hidden'}):
                        name = hidden.get('name')
                        value = hidden.get('value', '')
                        if name:
                            hidden_fields[name] = value
                    
                    return {
                        'action': action,
                        'method': method,
                        'username_field': username_field.get('name'),
                        'password_field': password_field.get('name'),
                        'hidden_fields': hidden_fields
                    }
            
            return None
            
        except Exception as e:
            print(f"❌ 解析登录表单失败: {e}")
            return None
    
    def attempt_login_with_form(self, form_info):
        """使用表单信息尝试登录"""
        print(f"\n🚀 使用表单登录: {form_info['action']}")
        
        # 用户凭据
        username = "154hdgrkk7@dpmurt.my"
        password = "5gHpr0V!"
        
        print(f"👤 用户名: {username}")
        print(f"🔑 密码: {password}")
        
        # 准备登录数据
        login_data = form_info['hidden_fields'].copy()
        login_data[form_info['username_field']] = username
        login_data[form_info['password_field']] = password
        
        # 可能的额外字段
        if 'credentialId' not in login_data:
            login_data['credentialId'] = ''
        
        print(f"📋 登录数据字段: {list(login_data.keys())}")
        
        # 设置请求头
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Origin": f"{urlparse(form_info['action']).scheme}://{urlparse(form_info['action']).netloc}",
            "Referer": form_info['action'],
            "Cache-Control": "max-age=0",
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "same-origin",
            "Sec-Fetch-User": "?1"
        }
        
        try:
            # 发送登录请求
            if form_info['method'] == 'POST':
                response = self.session.post(
                    form_info['action'],
                    data=login_data,
                    headers=headers,
                    allow_redirects=True,
                    timeout=30
                )
            else:
                response = self.session.get(
                    form_info['action'],
                    params=login_data,
                    headers=headers,
                    allow_redirects=True,
                    timeout=30
                )
            
            print(f"📊 登录响应状态码: {response.status_code}")
            print(f"🔗 登录后URL: {response.url}")
            
            return self.analyze_login_response(response)
            
        except Exception as e:
            print(f"❌ 登录请求失败: {e}")
            return False
    
    def analyze_login_response(self, response):
        """分析登录响应"""
        print("\n🔍 分析登录响应...")
        
        final_url = response.url.lower()
        response_text = response.text.lower()
        
        # 成功指标
        success_patterns = [
            "console" in final_url,
            "dashboard" in final_url,
            "account" in final_url,
            "profile" in final_url,
            "welcome" in response_text,
            "logout" in response_text
        ]
        
        # 失败指标
        failure_patterns = [
            "error" in final_url,
            "invalid" in response_text,
            "incorrect" in response_text,
            "failed" in response_text,
            "login" in final_url and "action" in final_url,
            response.status_code >= 400
        ]
        
        success_count = sum(1 for pattern in success_patterns if pattern)
        failure_count = sum(1 for pattern in failure_patterns if pattern)
        
        print(f"✅ 成功指标: {success_count}")
        print(f"❌ 失败指标: {failure_count}")
        
        if success_count > failure_count and response.status_code == 200:
            print("🎉 登录可能成功！")
            self.display_cookies()
            return True
        elif failure_count > 0:
            print("❌ 登录失败")
            self.extract_error_message(response)
            return False
        else:
            print("⚠️ 登录状态不确定")
            return None
    
    def display_cookies(self):
        """显示获取到的cookies"""
        if self.session.cookies:
            print(f"\n🍪 获取到 {len(self.session.cookies)} 个cookies:")
            for cookie in self.session.cookies:
                print(f"  - {cookie.name}: {cookie.value[:50]}...")
        else:
            print("\n🍪 未获取到cookies")
    
    def extract_error_message(self, response):
        """提取错误信息"""
        try:
            soup = BeautifulSoup(response.text, 'html.parser')
            
            # 查找错误信息
            error_selectors = [
                '.error', '.alert', '.message', '.notification',
                '[class*="error"]', '[class*="alert"]', '[id*="error"]'
            ]
            
            for selector in error_selectors:
                elements = soup.select(selector)
                for element in elements:
                    error_text = element.get_text().strip()
                    if error_text and len(error_text) < 200:
                        print(f"❌ 错误信息: {error_text}")
                        break
                        
        except Exception as e:
            print(f"❌ 提取错误信息失败: {e}")
    
    def test_api_endpoints(self):
        """测试可能的API登录端点"""
        print("\n🔌 测试API登录端点...")
        
        api_endpoints = [
            "https://www.codebuddy.ai/api/auth/login",
            "https://www.codebuddy.ai/api/login",
            "https://www.codebuddy.ai/auth/login",
            "https://www.codebuddy.ai/login/api"
        ]
        
        login_payload = {
            "username": "154hdgrkk7@dpmurt.my",
            "password": "5gHpr0V!",
            "email": "154hdgrkk7@dpmurt.my"
        }
        
        for endpoint in api_endpoints:
            try:
                print(f"\n📡 测试API: {endpoint}")
                
                # 尝试JSON格式
                headers = {"Content-Type": "application/json"}
                response = self.session.post(
                    endpoint,
                    json=login_payload,
                    headers=headers,
                    timeout=10
                )
                
                print(f"  JSON - 状态码: {response.status_code}")
                
                if response.status_code == 200:
                    print(f"  ✅ API响应成功")
                    try:
                        json_response = response.json()
                        print(f"  📋 响应: {json_response}")
                        return True
                    except:
                        print(f"  📋 响应: {response.text[:200]}...")
                
                # 尝试表单格式
                headers = {"Content-Type": "application/x-www-form-urlencoded"}
                response = self.session.post(
                    endpoint,
                    data=login_payload,
                    headers=headers,
                    timeout=10
                )
                
                print(f"  表单 - 状态码: {response.status_code}")
                
                if response.status_code == 200:
                    print(f"  ✅ 表单响应成功")
                    return True
                    
            except Exception as e:
                print(f"  ❌ API测试失败: {e}")
        
        return False
    
    def run_comprehensive_test(self):
        """运行综合登录测试"""
        print("=" * 60)
        print("🎯 CodeBuddy综合登录测试")
        print("=" * 60)
        
        # 方法1: 测试多个入口点
        print("\n📍 方法1: 测试网页登录入口点")
        form_info, response = self.test_multiple_entry_points()
        
        if form_info:
            login_success = self.attempt_login_with_form(form_info)
            if login_success:
                return True
        
        # 方法2: 测试API端点
        print("\n📍 方法2: 测试API登录端点")
        api_success = self.test_api_endpoints()
        if api_success:
            return True
        
        # 方法3: 使用原始fetch请求（已知会失败，但作为对比）
        print("\n📍 方法3: 使用原始fetch请求（对比测试）")
        self.test_original_fetch_request()
        
        return False
    
    def test_original_fetch_request(self):
        """测试原始的fetch请求（作为对比）"""
        print("🔄 测试原始fetch请求...")
        
        login_url = "https://www.codebuddy.ai/auth/realms/copilot/login-actions/authenticate?session_code=xxjnB7YjKIl_ajufRD5EqDl_yPvKhdn94um5DLP2DUo&execution=fddd3124-02c5-4e2e-9e11-2849f14b804f&client_id=console&tab_id=6MTzVOJ10oI&client_data=eyJydSI6Imh0dHBzOi8vd3d3LmNvZGVidWRkeS5haS9jb25zb2xlL2FjY291bnRzLy5hcGlzaXgvcmVkaXJlY3QiLCJydCI6ImNvZGUiLCJzdCI6ImFhNzllMDRiOTYzNDBkMTRhZjcwNGZjYWFiYzM5NWZkIn0"
        
        data = "username=154hdgrkk7%40dpmurt.my&password=5gHpr0V%21&credentialId="
        
        try:
            response = self.session.post(login_url, data=data, timeout=10)
            print(f"📊 原始请求状态码: {response.status_code}")
            print(f"🔗 原始请求最终URL: {response.url}")
            
            if response.status_code == 400:
                print("❌ 确认原始请求失败 (HTTP 400)")
            
        except Exception as e:
            print(f"❌ 原始请求异常: {e}")

def main():
    """主函数"""
    login_tester = ImprovedCodeBuddyLogin()
    success = login_tester.run_comprehensive_test()
    
    print("\n" + "=" * 60)
    print("📋 综合测试结果")
    print("=" * 60)
    
    if success:
        print("✅ 找到可用的登录方法！")
        print("🎉 CodeBuddy登录测试成功")
    else:
        print("❌ 所有登录方法都失败了")
        print("💡 可能的原因:")
        print("  1. 网站结构发生变化")
        print("  2. 需要额外的认证步骤")
        print("  3. 用户凭据无效")
        print("  4. 网站有反自动化保护")

if __name__ == "__main__":
    main()